package com.patchmanage.back.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patchmanage.back.annotation.LoginValidate;
import com.patchmanage.back.annotation.OperLog;
import com.patchmanage.back.entity.Patch;
import com.patchmanage.back.entity.PatchGroup;
import com.patchmanage.back.entity.PatchGroupRel;
import com.patchmanage.back.result.Result;
import com.patchmanage.back.service.IPatchGroupRelService;
import com.patchmanage.back.service.IPatchGroupService;
import com.patchmanage.back.service.IPatchService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  补丁控制器
 * </p>
 *
 * @author huizhao
 * @since 2021-03-20
 */
@Api(value = " 补丁 controller", tags = {"补丁 Api"})
@RestController
@RequestMapping("/back/patch")
public class PatchController {


    @Autowired
    public IPatchService iPatchService;

    @Autowired
    public IPatchGroupService patchGroupService;

    @Autowired
    public IPatchGroupRelService patchGroupRelService;


    /**
     * 分页获取补丁列表接口
     *
     * @param dict
     * @return
     */
    @ApiOperation(value = "分页获取补丁列表接口", notes = "分页获取补丁列表接口")
    @RequestMapping(value = "list", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "patchNo", value = "patchNo", required = false, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "abs", value = "abs", required = false, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "patchGroupId", value = "patchGroupId", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "dangerLv", value = "dangerLv", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "adaptationOs", value = "adaptationOs", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "patchTypes", value = "patchTypes", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "isOfficialMark", value = "isOfficialMark", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "isBlacklist", value = "isBlacklist", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "publishingTime", value = "publishingTime", required = false, dataType = "Date", paramType = "body"),
            @ApiImplicitParam(name = "blacklistCause", value = "blacklistCause", required = false, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "search", value = "search", required = false, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "pageNo", value = "pageNo", required = true, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "pageSize", value = "pageSize", required = true, dataType = "Integer", paramType = "body")
    })
    public Result<IPage<Patch>> list(@ApiIgnore @RequestBody Dict dict) {

        Page<Patch> page = new Page(dict.getInt("pageNo"), dict.getInt("pageSize"));
        QueryWrapper<Patch> queryWrapper = new QueryWrapper<>();

        if(StrUtil.isNotBlank(dict.getStr("patchNo"))){
            queryWrapper.like("patch_no", dict.getStr("patchNo"));
        }
        if(StrUtil.isNotBlank(dict.getStr("abs"))){
            queryWrapper.like("abs", dict.getStr("abs"));
        }
        if(dict.getInt("patchGroupId") != null){
            PatchGroup patchGroup = patchGroupService.getById(dict.getInt("patchGroupId"));
            queryWrapper.like("patch_group_name", patchGroup.getName());
        }
        if(StrUtil.isNotBlank(dict.getStr("blacklistCause"))){
            queryWrapper.eq("blacklist_cause", dict.getStr("blacklistCause"));
        }
        if(dict.getInt("adaptationOs") != null){
            queryWrapper.eq("adaptation_os", dict.getInt("adaptationOs"));
        }
        if(dict.getInt("patchTypes") != null){
            queryWrapper.eq("patch_types", dict.getInt("patchTypes"));
        }
        if(dict.getInt("dangerLv") != null){
            queryWrapper.eq("danger_lv", dict.getInt("dangerLv"));
        }
        if(dict.getInt("isOfficialMark") != null){
            queryWrapper.eq("is_official_mark", dict.getInt("isOfficialMark"));
        }
        if(dict.getInt("isBlacklist") != null){
            queryWrapper.eq("is_blacklist", dict.getInt("isBlacklist"));
        }
        if(dict.getDate("publishingTime") != null){
            queryWrapper.between("publishing_time", DateUtil.beginOfDay(dict.getDate("publishingTime")),DateUtil.endOfDay(dict.getDate("publishingTime")));
        }
        if(StrUtil.isNotBlank(dict.getStr("search"))){
            queryWrapper.and(wrapper -> wrapper.like("patch_no", dict.getStr("search"))
                    .or().like("abs", dict.getStr("search"))
                    .or().like("cve_affect_packages", dict.getStr("search"))
                    .or().like("cve_id", dict.getStr("search")));
        }
        queryWrapper.orderByDesc("publishing_time");
        return Result.success(iPatchService.page(page, queryWrapper));
    }

    /**
     * 获取补丁接口
     *
     * @param dict
     * @return
     */
    @ApiOperation(value = "获取补丁接口", notes = "获取补丁接口")
    @RequestMapping(value = "getById", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Integer", paramType = "body")
    })
    public Result<Patch> getById(@ApiIgnore @RequestBody Dict dict) {
        return Result.success(iPatchService.getById(dict.getInt("id")));
    }


    /**
     * 设置正式补丁
     * @param dict
     * @return
     */
    @ApiOperation(value = "设置正式非正式补丁接口", notes = "设置正式补丁接口")
    @RequestMapping(value = "setOfficialMark", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "isOfficialMark", value = "isOfficialMark", required = true, dataType = "Integer", paramType = "body")
    })
    @OperLog(operModul="补丁",operDesc="设置正式非正式补丁")
    public Result<Boolean> setOfficialMark(@ApiIgnore @RequestBody Dict dict) {

        Patch patch = new Patch();
        patch.setIsOfficialMark(dict.getInt("isOfficialMark"));
        patch.setRegularTime(LocalDateTime.now());

        String ids = dict.getStr("id");

        List<String> list = Arrays.asList(ids.split(","));

        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("id",list);

        return Result.success(iPatchService.update(patch, updateWrapper));
    }

    /**
     * 设置自动转正
     * @param dict
     * @return
     */
    @ApiOperation(value = "设置自动转正接口", notes = "设置自动转正接口")
    @RequestMapping(value = "setAutoOfficialMark", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "isAutoOfficialMark", value = "isAutoOfficialMark", required = false, dataType = "Integer", paramType = "body"),
            @ApiImplicitParam(name = "autoOfficialHour", value = "autoOfficialHour", required = false, dataType = "Integer", paramType = "body")
    })
    @OperLog(operModul="补丁",operDesc="设置正式非正式补丁")
    public Result<Boolean> setAutoOfficialMark(@ApiIgnore @RequestBody Dict dict) {

        if(dict.getInt("isAutoOfficialMark") == 1){
            Patch patch = new Patch();
            patch.setPrepareRegularTime(LocalDateTime.now());
            patch.setAutoOfficialHour(dict.getInt("autoOfficialHour"));
            String ids = dict.getStr("id");
            List<String> list = Arrays.asList(ids.split(","));
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.in("id",list);
            iPatchService.update(patch, updateWrapper);
        }

        return Result.success(true);
    }

    /**
     * 设置解除黑名单补丁接口
     * @param dict
     * @return
     */
    @ApiOperation(value = "设置解除黑名单补丁接口", notes = "设置解除黑名单补丁接口")
    @RequestMapping(value = "setBlackList", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ids", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "isBlacklist", value = "isBlacklist", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "blacklistCause", value = "blacklistCause", required = true, dataType = "String", paramType = "body")
    })
    @OperLog(operModul="补丁",operDesc="设置解除黑名单补丁")
    public Result<Boolean> setBlackList(@ApiIgnore @RequestBody Dict dict) {


        Patch patch = new Patch();
        patch.setIsBlacklist(dict.getInt("isBlacklist"));
        patch.setBlacklistCause(dict.getStr("blacklistCause"));

        String ids = dict.getStr("ids");

        List<String> list = Arrays.asList(ids.split(","));

        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("id",list);
        return Result.success(iPatchService.update(patch,updateWrapper));
    }

    /**
     * 设置补丁组接口
     * @param dict
     * @return
     */
    @ApiOperation(value = "设置补丁组接口", notes = "设置补丁组接口")
    @RequestMapping(value = "setPatchGroup", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ids", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "groupId", value = "groupId", required = true, dataType = "String", paramType = "body")
    })
    @Transactional(rollbackFor = Exception.class)
    @OperLog(operModul="补丁",operDesc="设置补丁组")
    public Result<Boolean> setPatchGroup(@ApiIgnore @RequestBody Dict dict) {


        String ids = dict.getStr("ids");
        String groupIds = dict.getStr("groupIds");

        List<String> idsList = Arrays.asList(ids.split(","));
        List<String> groupIdsList = Arrays.asList(groupIds.split(","));


        //删除补丁和组的关联
        QueryWrapper<PatchGroupRel> patchGroupRelQueryWrapper = new QueryWrapper<>();
        patchGroupRelQueryWrapper.in("patch_id",idsList);
        patchGroupRelService.remove(patchGroupRelQueryWrapper);

        //获取补丁组列表
        StrBuilder builder = StrBuilder.create();

        //插入新的补丁和组的关联
        for(String id : idsList){
            for(String groupId : groupIdsList) {

                PatchGroup pg = patchGroupService.getById(Integer.valueOf(groupId));

                PatchGroupRel patchGroupRel = new PatchGroupRel();
                patchGroupRel.setPatchId(Integer.valueOf(id));
                patchGroupRel.setPatchGroupId(Integer.valueOf(groupId));
                patchGroupRel.setPatchGroupName(pg.getName());
                patchGroupRel.setUtime(LocalDateTime.now());

                builder.append(pg.getName()).append(",");

                patchGroupRelService.save(patchGroupRel);
            }


            builder.subString(0,builder.length()-1);

            Patch patch = new Patch();
            patch.setId(Integer.valueOf(id));
            patch.setPatchGroupName(builder.toString());
            iPatchService.updateById(patch);
            builder.reset();
        }

        return Result.success(true);
    }

    /**
     * 删除补丁
     * @param dict
     * @return
     */
    @ApiOperation(value = "删除补丁接口", notes = "删除补丁接口")
    @RequestMapping(value = "removeById", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Integer", paramType = "body"),
    })
    @LoginValidate
    @Transactional(rollbackFor = Exception.class)
    @OperLog(operModul="补丁",operDesc="删除补丁")
    public Result<Boolean> removeById(@ApiIgnore @RequestBody Dict dict) {


        String id = dict.getStr("id");
        String[] ids = id.split(",");

        //删除补丁和组的关联
        List<String> idsList = Arrays.asList(ids);
        QueryWrapper<PatchGroupRel> patchGroupRelQueryWrapper = new QueryWrapper<>();
        patchGroupRelQueryWrapper.in("patch_id",idsList);
        patchGroupRelService.remove(patchGroupRelQueryWrapper);

        //删除补丁
        return Result.success(iPatchService.removeByIds( Arrays.asList(ids)));
    }
}
